package com.zhucan.elastics.application.query.impl;

import com.zhucan.elastics.application.command.assembler.EmployeeAssembler;
import com.zhucan.elastics.application.query.EmployeeQueryService;
import com.zhucan.elastics.application.query.dto.EmployeeDTO;
import com.zhucan.elastics.application.query.qry.EmployeeQry;
import com.zhucan.elastics.domain.Employee;
import com.zhucan.elastics.domain.EmployeeRepository;
import lombok.AllArgsConstructor;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: zhuCan
 * @date: 2019/12/20 11:02
 * @description:
 */
@Service
@AllArgsConstructor
public class EmployeeQueryServiceImpl implements EmployeeQueryService {

  private EmployeeAssembler employeeAssembler;

  private EmployeeRepository employeeRepository;

  @Override
  public Page<EmployeeDTO> employeePage(EmployeeQry qry, Pageable pageable) {

    BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

    if (qry.getAge() != null) {
      boolQueryBuilder.must(QueryBuilders.termQuery("age", qry.getAge()));
    }
    if (!StringUtils.isEmpty(qry.getDesc())) {
      boolQueryBuilder.must(QueryBuilders.matchQuery("desc", qry.getDesc()));
    }
    if (!StringUtils.isEmpty(qry.getName())) {
      boolQueryBuilder.must(QueryBuilders.wildcardQuery("name", "*" + qry.getName() + "*"));
    }
    if (qry.getStart() != null || qry.getEnd() != null) {
      RangeQueryBuilder entryTime = QueryBuilders.rangeQuery("entryTime");
      boolQueryBuilder.must(entryTime);
      if (qry.getStart() != null) {
        entryTime.gt(qry.getStart().getTime());
      }
      if (qry.getEnd() != null) {
        entryTime.lte(qry.getEnd().getTime());
      }
    }
    if (!StringUtils.isEmpty(qry.getNo())) {
      boolQueryBuilder.must(QueryBuilders.fuzzyQuery("no", qry.getNo()));
    }

    Page<Employee> result = employeeRepository.search(boolQueryBuilder, pageable);

    return employeeAssembler.convertDtoPage(result);
  }

  @Override
  public List<EmployeeDTO> findByNameLike(String name) {
    return employeeAssembler.convertDTOs(employeeRepository.findByNameLike("*" + name.trim() + "*").filter(x -> x.getDeleted() != null && !x.getDeleted()).collect(Collectors.toList()));
  }
}
